# -*- coding: utf-8 -*-
import random, string
from api import api, ERROR_CLASS, GlobalError
from config import OSS_BUCKET, OSS_APP_KEY, OSS_APP_ID, OSS_HOST
from flask import jsonify, request
import json
from lib.oss.oss_api import *
from model.classification import Classification
from time import time
from werkzeug.exceptions import NotFound


class Error:
    CLASS_ID_INVALID = {
        'err': ERROR_CLASS + 1,
        'msg': 'Classification ID Invalid'
    }
    CLASS_EXISTS = {
        'err': ERROR_CLASS + 2,
        'msg': 'Classification Exists'
    }
    CLASS_PARAMETER_INVALID = {
        'err': ERROR_CLASS + 3,
        'msg': 'Classification Parameter Invalid'
    }
    INFO_UPDATE_FAILURE = {
        'err': ERROR_CLASS + 4,
        'msg': 'Info Update Failure'
    }
    INFO_REMOVE_FAILURE = {
        'err': ERROR_CLASS + 5,
        'msg': 'Info Remove Failure'
    }



@api.route('/classification', methods=['POST'])
def new_classification():
    """
## Create new classification

    POST /api/classification

Parameters:

* `class_name` (string, required) - name of classification
* `superiorId` (string, required) - ID of superior
* `nodeType` (int, required) - type of classification
* `icon` (string) - url of icon

Return:

* `classId`: classification ID

Errors: `5001`, `5002`, `5003`
    """

    class_name = request.form.get('class_name', None)
    superior_id = request.form.get('superiorId', '')
    url = request.form.get('icon', '')

    if class_name is None:
           return jsonify(stat=0, **Error.CLASS_PARAMETER_INVALID), 403
    if superior_id != '':
        try:
            superclass = Classification.get({Classification.Field._id: superior_id})
            if superclass.data.get(Classification.Field.type) == 1:
                return jsonify(stat=0, **Error.INFO_UPDATE_FAILURE), 403
            else:
                node_type = superclass.data.get(Classification.Field.type) - 1
        except NotFound:
            return jsonify(stat=0, **Error.CLASS_ID_INVALID), 403
    else:
        node_type = request.form.get('nodeType', 0, type=int)

    try:
        Classification.get({
            Classification.Field.name: class_name,
            Classification.Field.superior: superior_id
        })
    except NotFound:
        class_id = Classification.new_classification(class_name, superior_id, node_type, url)
        if superior_id != '':
            Classification.add_subclass(superior_id, class_id, class_name, url, node_type)
            while superior_id != '':
                Classification.collection.update({
                    Classification.Field._id: superior_id
                }, {
                    '$set': {
                        Classification.Field.updateTime: int(time() * 1000)
                    }
                })
                classification = Classification.get({
                    Classification.Field._id: superior_id
                })
                superior_id = classification.data.get(Classification.Field.superior)
        return jsonify(stat=1, classId=class_id)
    return jsonify(stat=0, **Error.CLASS_EXISTS), 403


@api.route('/classification/<class_id>', methods=['PUT'])
def update_classification(class_id):
    """

## update classification's icon

    PUT /api/classification/<class_id>

Parameters:

* `icon` (string) - url of icon

Errors: `5001`, `5004`
    """

    query={}
    url = request.form.get('icon', '')

    query[Classification.Field.icon] = url

    try:
        Classification.collection.update({
            Classification.Field._id: class_id
        }, {
            '$set': query
        })
    except NotFound:
        return jsonify(stat=0, **Error.CLASS_ID_INVALID), 403
    except:
        return jsonify(stat=0, **Error.INFO_UPDATE_FAILURE)

    return jsonify(stat=1)




@api.route('/classification/<class_id>', methods=['GET'])
def get_classification(class_id):
    """
## Get all sub classifications or images of this classification

    GET /api/classification/<class_id>

Return:

* `classification` (dict)
    * `_id` (string) - ID of this classification
    * `name` (string) - name of this classification
    * `subclass` ([dict]) - all sub classification
        * `name` - name of sub classification
        * `_id` - ID of sub classification
        * `icon` - url of icon
        * `type` - type of classification
    * `image` ([dict]) - list of images
        * `url` (string) - url of image
        * `authorId` (string) - ID of author
        * `tags` ([string]) - list of tags
    * `superior` (string) - superior's ID
    * `type` (int) - 4 表示转跳到文字菜单, 1 表示叶子节点，下级只有图片, 0 转跳到画室, 其他表示转跳到有图片的页面
* `path` ([dict]) - path to this classification
    * `title` (string) - name
    * `href` (string) - url of this classification

Errors: `5001`
    """

    try:
        classification = Classification.get({
            Classification.Field._id: class_id
        })
    except NotFound:
        return jsonify(stat=0, **Error.CLASS_ID_INVALID), 403
    path = [{
        'title': '图库',
        'href': 'gallery.html'
    }]
    if classification.data.get(Classification.Field.superior) != '':
        superior = Classification.get({
            Classification.Field._id: classification.data.get(Classification.Field.superior)
        })
        path.append({
            'title': superior.data.get(Classification.Field.name),
            'href': "galleryText.html?class_id=%s"% (superior.data.get(Classification.Field._id))
        })
    path.append({
        'title': classification.data.get(Classification.Field.name),
        'href': ''
    })
    return jsonify(stat=1, classification=classification.data, path=path)


@api.route('/classification/<class_id>/image', methods=['POST'])
def upload_image(class_id):
    """
### Upload an image

    POST /api/classification/<class_id>/image

Parameters:

* `image` ([url]) - the image's url to upload
* `authorId` (string) - Id of author
* `tags` (string) - tags, 用'一个空格'隔开

Return:

* `imageUrl` (string) - the image url on Aliyun
    """

    classification = Classification.get({
        Classification.Field._id: class_id
    }, [
        Classification.Field.type
    ])
    if classification.data.get(Classification.Field.type) != 1:
        return jsonify(stat=0, **Error.INFO_UPDATE_FAILURE), 403
    url = json.loads(request.form.get('image'))
    print type(url)
    print url
    author_id = request.form.get('authorId')
    tag = request.form.get('tags', '')

    tags = list(set(tag.split(' ')))
    if '' in tags:
        tags.remove('')

    print type(url)
    print url

    cur_id = class_id
    while cur_id != '':
        Classification.collection.update({
            Classification.Field._id: cur_id
        }, {
            '$set': {
                Classification.Field.updateTime: int(time() * 1000)
            }
        })
        classification = Classification.get({
            Classification.Field._id: cur_id
        })
        cur_id = classification.data.get(Classification.Field.superior)
    for img in url:
        Classification.add_image(class_id, img, author_id, tags)

    return jsonify(stat=1, imageUrl=url)


@api.route('/classification/index', methods=['GET'])
def get_index():
    """
### Get classification of index

    GET /api/classification/index

Return:

* `contentData` ([dict]) - list of dict, info of classifications
    * `href` (string) - url of this classification
    * `name` (string) - name of classification
    * `icon` (string) - url of cover
    * `superior` (string) - ID of superior
    * `_id` (string) - ID of this classification (for app)
    * `updateTime` (long) - 更新时间
    """

    classifications = Classification.find({
        Classification.Field.superior: ''
    }, [
        Classification.Field._id,
        Classification.Field.name,
        Classification.Field.type,
        Classification.Field.superior,
        Classification.Field.icon,
        Classification.Field.updateTime,
        Classification.Field.type
    ])
    content_data = []
    for classification in classifications:
        if classification.get(Classification.Field.type) == 4:
            href = "galleryText.html?class_id=%s"% (classification.get(Classification.Field._id))
        else:
            if classification.get(Classification.Field.type) == 0:
                href = "studios.html"
            else:
                href = "galleryImg.html?class_id=%s"% (classification.get(Classification.Field._id))
        name = classification.get(Classification.Field.name)
        icon = classification.get(Classification.Field.icon)
        superior = classification.get(Classification.Field.superior)
        _id = classification.get(Classification.Field._id)
        update_time = classification.get(Classification.Field.updateTime)
        node_type = classification.get(Classification.Field.type)
        content_data.append({
            'href': href,
            'name': name,
            'icon': icon,
            'superior': superior,
            '_id':_id,
            'updateTime': update_time,
            'type': node_type
        })

    return jsonify(stat=1, contentData=content_data)

@api.route('/classification/<class_id>/subclasses', methods=['GET'])
def get_all_subclass(class_id):
    """
### Get all sub-classification info

    Get /api/classification/<class_id>/subclasses

Return:
* `contentData ([dict]) - each one is a subclassification
    * `title` (string) - name of this classification
    * `images` ([dict]) - urls of all images
        * `url` (string) - url of image
        * `authorId` (string) - ID of author
        * `tags` ([string]) - list of tags
    """

    subclass = Classification.find({
        Classification.Field.superior: class_id
    }, [
        Classification.Field.name,
        Classification.Field.image
    ])
    contentData = []
    if len(subclass) == 0:
        subclass = Classification.get({
            Classification.Field._id: class_id
        })
        contentData.append({
            'title': subclass.data.get(Classification.Field.name),
            'images': subclass.data.get(Classification.Field.image)
        })
    else:
        for classification in subclass:
            images = classification.get(Classification.Field.image, [])
            contentData.append({
                'title': classification.get(Classification.Field.name),
                'images': images
            })
    return jsonify(stat=1, contentData=contentData)

@api.route('/classification/<class_id>/list', methods=['GET'])
def get_list(class_id):
    """
### Get sub list of classification

    GET /api/classification/<class_id>/list

Return:

* `list` ([dict]) - list of sub-classification
    * `href` (string) - url of this classification
    * `title` (string) - name of this classification
    * `icon` (string) - url of icon
    * `updateTime` (long) - 更新时间
    * `_id` (string)
    * `nodeType` (string)
* `path` ([dict]) - path to this classification
    * `title` (string) - name
    * `href` (string) - url of this classification

Error: `5001`
    """

    try:
        classification = Classification.get({
            Classification.Field._id: class_id
        }, [
            Classification.Field.name,
            Classification.Field.subclass,
            Classification.Field.superior
        ])
    except NotFound:
        return jsonify(stat=0, **Error.CLASS_ID_INVALID), 403
    classifications = classification.data.get(Classification.Field.subclass, [])
    list = []
    for subclass in classifications:
        href = "galleryImg.html?class_id=%s"% (subclass.get(Classification.Subclass._id))
        title = subclass.get(Classification.Subclass.name)
        icon = subclass.get(Classification.Subclass.icon)
        update_time = Classification.get({
            Classification.Field._id:subclass.get(Classification.Subclass._id)
        }).data.get(Classification.Field.updateTime)
        Id = subclass.get(Classification.Subclass._id)
        type = subclass.get(Classification.Subclass.type)
        list.append({
            'href': href,
            'title': title,
            'icon': icon,
            'updateTime': update_time,
            '_id': Id,
            'nodeType': type
        })
    path = [{
        'title': '图库',
        'href': 'gallery.html'
    }, {
        'title': classification.data.get(Classification.Field.name),
        'href': ''
    }]
    return jsonify(stat=1, path=path, list=list)

@api.route('/classification/remove/<class_id>', methods=['DELETE'])
def remove(class_id):
    """
### 删除某分类以及其所有子分类

    DELETE /api/classification/remove/<class_id>

Error: `5001`, `5005`
    """

    try:
        classification = Classification.get({
            Classification.Field._id: class_id
        }, [
            Classification.Field.subclass,
            Classification.Field.name,
            Classification.Field.icon,
            Classification.Field._id,
            Classification.Field.superior,
            Classification.Field.type
        ])
    except NotFound:
        return jsonify(stat=0, **Error.CLASS_ID_INVALID), 403
    classifications = classification.data.get(Classification.Field.subclass, [])
    for subclass in classifications:
        _id = subclass.get(Classification.Subclass._id)
        remove(_id)
    superior = classification.data.get(Classification.Field.superior)
    if superior != '':
        superclass = Classification.get({
            Classification.Field._id: superior
        })
        superclass.update({
            '$pull' : {
                Classification.Field.subclass : {
                    Classification.Subclass._id : classification.data.get(Classification.Field._id),
                    Classification.Subclass.icon : classification.data.get(Classification.Field.icon),
                    Classification.Subclass.name : classification.data.get(Classification.Field.name),
                    Classification.Subclass.type : classification.data.get(Classification.Field.type)
                }
            }
        })
    try:
        Classification.remove({
            Classification.Field._id: class_id
        })
    except NotFound:
        return jsonify(stat=0, **Error.CLASS_ID_INVALID), 403
    except:
        return jsonify(stat=0, **Error.INFO_REMOVE_FAILURE), 403
    return jsonify(stat=1)



from flask import render_template, url_for, redirect
import json
@api.route('/classAdmin/<cid>')
def classAdmin(cid):
    listImg = False
    me = "me"
    if cid == '0':
        classifications = Classification.find({
                Classification.Field.superior: ''
            }, [
                Classification.Field._id,
                Classification.Field.name,
                Classification.Field.icon,
                Classification.Field.subclass
            ])
    else:
        result = Classification.find({
                Classification.Field._id: cid
            }, [
                Classification.Field._id,
                Classification.Field.subclass,
                Classification.Field.image
            ])
        classifications = [];
        me = result[0]
        sub = result[0].get(Classification.Field.subclass)
        if not sub:
            listImg = True;

        for cc in sub:
            ccc = Classification.find({
                Classification.Field._id: cc.get(Classification.Field._id)
            }, [
                Classification.Field._id,
                Classification.Field.name,
                Classification.Field.icon,
                Classification.Field.subclass
            ])
            if ccc:
                classifications.append(ccc[0])

    content_data = []
    for classification in classifications:
        id = classification.get(Classification.Field._id)
        name = classification.get(Classification.Field.name)
        icon = classification.get(Classification.Field.icon)
        content_data.append({
            'id': id,
            'name': name,
            'icon': icon,
        })
    #print(url_for('classAdmin', id='0'))
    #return url_for('api.classAdmin', id='557f7d9ec917534df3dc68d3')
    meJson = json.dumps(me)
    print("json:", meJson)
    return render_template('classAdmin.html', content=content_data, listImg=listImg, me=me, meJson=meJson)

from model.classification import Classification as CCC
@api.route('/classAddImg', methods=['POST'])
def classAddImg():
    data = request.form.get('urls', None)
    class_id = request.form.get('class_id', None)
    # me = json.loads(request.form.get('me', json.dumps("me")))
    meJson = request.form.get('me', None)
    me = json.loads(meJson)
    data = data.replace('\r\n', '\n')
    data = data.split('\n')
    for url in data:
        CCC.add_image(class_id, url, "unknow now", []);
    return classAdmin(cid=me.get('_id'))

@api.route('/classRemoveImg', methods=['POST'])
def classRemoveImg():
    class_id = request.form.get('class_id', None)
    url = request.form.get('url', None)
    CCC.remove_image(class_id, url)
    return classAdmin(cid=class_id)